package ext.tianma.project2.APQP.service;

import java.io.File;
import java.io.IOException;
import java.rmi.RemoteException;
import java.sql.Blob;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;
import org.dom4j.DocumentException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.remoting.support.RemoteAccessor;
import org.springframework.stereotype.Service;

import wt.doc.WTDocument;
import wt.fc.ObjectReference;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.collections.WTArrayList;
import wt.fc.collections.WTHashSet;
import wt.folder.Folder;
import wt.inf.container.WTContainerRef;
import wt.inf.team.ContainerTeamManagedInfo;
import wt.inf.team.ContainerTeamManagedState;
import wt.org.WTPrincipalReference;
import wt.org.WTUser;
import wt.ownership.Ownership;
import wt.part.WTPart;
import wt.projmgmt.admin.Project2;
import wt.session.SessionHelper;
import wt.type.TypedUtility;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
import wt.vc.Iterated;
import wt.vc.VersionReference;
import wt.vc.views.ViewException;
import wt.workflow.engine.WfProcess;

import com.ptc.core.lwc.server.PersistableAdapter;
import com.ptc.projectmanagement.deliverable.PlanDeliverable;
import com.ptc.projectmanagement.deliverable.PlanDeliverableLink;
import com.ptc.projectmanagement.plan.DateConstraint;
import com.ptc.projectmanagement.plan.Duration;
import com.ptc.projectmanagement.plan.HealthStatusType;
import com.ptc.projectmanagement.plan.Plan;
import com.ptc.projectmanagement.plan.PlanActivity;
import com.ptc.projectmanagement.plan.PlanHelper;
import com.ptc.projectmanagement.plan.Plannable;
import com.ptc.projectmanagement.plan.PlannableState;
import com.ptc.projectmanagement.util.AdminUtils;
import com.ptc.projectmanagement.util.ProcessorUtils;

import ext.com.iba.IBAUtil;
import ext.tianma.bom.util.DBUtil;
import ext.tianma.bom.util.EnumerationUtil;
import ext.tianma.bom.util.GenericUtil;
import ext.tianma.model.FormDataXml;
import ext.tianma.number.util.PartUtil;
import ext.tianma.part.PartWorkflowUtil;
import ext.tianma.project2.APQP.bean.APQPPlanactivityBean;
import ext.tianma.project2.APQP.constants.APQPProjectConstant;
import ext.tianma.project2.util.ProjectUtil;
import ext.tianma.util.TMUtil;
import ext.tianma.util.UserUtil;

@Service
public class APQPPlanActivityService extends RemoteAccessor{
	
	@Autowired
	APQPProjectService projectservice;
	
	@Autowired
	ProcessService processService;
	
	//AQPQ活动的标准属性，请不要改变属性顺序
	private final String[] PLANACTIVITY_MDA_ATTRS = {"materialCategory","apqp","pn","isUpload","isStandard","hierarchy","supplier"};
	
	public static final String MATERIALCATEGORY_SPLIT = "--";
	
	//APQP活动枚举：  key：标准属性key   value：枚举名称key
	private static final Map<String,String> PLANACTIVITY_ENUM_ATTRS2 = new HashMap<String, String>();
	static {
		PLANACTIVITY_ENUM_ATTRS2.put("isUpload", "isBoolean");
		PLANACTIVITY_ENUM_ATTRS2.put("isStandard", "isBoolean");
	}
	
	/**
	 * 批量创建一级活动
	 * @param project2
	 * @throws IOException
	 * @throws WTException
	 * @throws WTPropertyVetoException
	 * @author xucr
	 * @throws DocumentException 
	 * @throws JSONException 
	 * @CreateDate 2020年8月13日
	 */
	public void batchCreatePlanActivity(Project2 project2, JSONArray planBean, String [] phases) throws IOException, WTException, WTPropertyVetoException, DocumentException, JSONException {
		Plan plan = (Plan) PlanHelper.service.getPlan(ObjectReference.newObjectReference(project2));
		
		int parentNum = 1;
		int childNum = 1;
		PlanActivity parentPlan = null;
		for(int i = 0 ; i < planBean.length(); i++) {
			JSONObject obj = planBean.getJSONObject(i);
			String userName = obj.getString("owner");
			String materialCategory = obj.getString("materialCategory");
			String planName = "";
			if(StringUtils.isNotEmpty(materialCategory)) {
				if(materialCategory.indexOf(MATERIALCATEGORY_SPLIT) > -1) {
					planName = materialCategory.split(MATERIALCATEGORY_SPLIT)[0].trim();
				} else {
					planName = materialCategory.trim();
				}
			}
			String pn = obj.getString("pn");
			String supplier = obj.getString("supplier");
			WTUser user = UserUtil.getUserByName(userName);
			Map<String, String> map = getMinMax(obj, phases);
			String min = map.get("min");
			String max = map.get("max");
			
			//创建一级计划：一级计划仅用来管理一行数据，这里默认给一个时间
			APQPPlanactivityBean bean1 = initPlanBean(planName, parentNum, min, max, (WTUser)project2.getCreator());
			obj.put("hierarchy", "L1");
			parentPlan = createPlanActivity(project2, 
					ObjectReference.newObjectReference(plan), ObjectReference.newObjectReference(plan), bean1, obj, true);
			
			//创建二级计划
			for(int j = 0 ; j < phases.length; j++) {
				String date = getDate(obj.get(phases[j]));
				
				obj.put("isUpload", APQPProjectConstant.NO);
				obj.put("isStandard", APQPProjectConstant.NO);
				obj.put("hierarchy", "L2");
				obj.put("pn", pn);
				obj.put("supplier", supplier);
				obj.put("apqp", phases[j]);
				APQPPlanactivityBean bean = initPlanBean(planName + "_" + phases[j] + "_" + (i +1), childNum, date, date, user);
				createPlanActivity(project2, 
						ObjectReference.newObjectReference(plan), ObjectReference.newObjectReference(parentPlan), bean, obj, false);
				
				childNum++;
			}
			parentNum++;
		}
	}
	
	/**
	 * 得到最大、最小时间
	 * @param obj
	 * @param phaseKeys
	 * @throws JSONException
	 * @author xucr
	 * @CreateDate 2020年9月16日
	 */
	public Map<String, String> getMinMax(JSONObject obj, String[] phaseKeys) throws JSONException {
		String min = "";
		String max = "";
		Long minLong = 9999999999L;
		Long maxLong = 0L;
		Map<String, String> map = new HashMap<String, String>();
		for(int j = 0 ; j < phaseKeys.length; j++) {
			Object dateObj = obj.get(phaseKeys[j]);
			String date = "";
			if(dateObj instanceof JSONArray) {
				date = ((JSONArray) dateObj).getString(0);
			} else if(dateObj instanceof String) {
				date = (String) dateObj;
			}
			
			if(StringUtils.isNotEmpty(date)) {
				long longDate = Long.valueOf(date.replaceAll("[-\\s:]",""));
				//取最大
				if(maxLong < longDate) {
					maxLong = longDate;
					max = date;
				}
				
				//取最小
				if(minLong > longDate) {
					minLong = longDate;
					min = date;
				}
			}
		}
		map.put("min", min);
		map.put("max", max);
		return map;
	}
	
	/**
	 * 批量更新活动
	 * @param project2
	 * @param planBean
	 * @throws IOException
	 * @throws WTException
	 * @throws WTPropertyVetoException
	 * @throws DocumentException
	 * @throws JSONException
	 * @author xucr
	 * @CreateDate 2020年9月7日
	 */
	public void batchUpdaatePlanActivity(
			Project2 project2, JSONArray planBean) throws IOException, WTException, WTPropertyVetoException, DocumentException, JSONException {
		
		/**
		 * 只有草稿项目才能更新活动
		 * 运行项目中的活动，不允许编辑
		 * */
		String [] stdAttrs = {"apqp"};
		JSONObject attrs = null;
		WTHashSet set = new WTHashSet();
		
		for(int i = 0 ; i < planBean.length(); i++) {
			JSONObject obj = planBean.getJSONObject(i);
			Iterator<String> it = obj.keys();
			while(it.hasNext()) {
				String key = it.next();
				if(key.contains(APQPProjectConstant.PLANACTIVITYOID)) {
					attrs = new JSONObject();
					PlanActivity activity = (PlanActivity) TMUtil.oid2Obj(obj.getString(key));
					getPlanactivitySTDAttr(activity, stdAttrs, attrs);
					
					String apqp = attrs.getString("apqp");
					String date = getDate(obj.get(apqp));
					String owner = obj.getString("owner"); //一行数据中，owner相同
					List<WTUser> users = ProjectUtil.getUserList(owner);
					if(users.size() > 0) {
						WTUser user = users.get(0);
						activity.setOwnership(Ownership.newOwnership(user));
					}
					
					activity.setStartDate(TMUtil.getTimestamp(date + " 9:00:00"));
					activity.setFinishDate(TMUtil.getTimestamp(date + " 9:00:00"));
					set.add(activity);
				}
			}
		}
		
		if(set.size() > 0) {
			PersistenceHelper.manager.save(set);
		}
	}
	
	/**
	 * 构造活动bean
	 * @param name
	 * @param num
	 * @param date
	 * @param user
	 * @param rootRef
	 * @param parentRef
	 * @param planactivity
	 * @return
	 * @author xucr
	 * @CreateDate 2020年8月21日
	 */
	private APQPPlanactivityBean initPlanBean(String name, int num, String startDate, String finshDate, WTUser user) {
		APQPPlanactivityBean bean = new APQPPlanactivityBean();
		
		bean.setPlanName(name);
		bean.setLineNumber(num);
		if(StringUtils.isNotEmpty(startDate)) {
			bean.setStartdate(startDate + " 9:00:00");
		}
		if(StringUtils.isNotEmpty(finshDate)) {
			bean.setFinishdate(finshDate + " 9:00:00");
		}
		bean.setUser(user);
		
		return bean;
	}
	
	/**
	 * 创建活动
	 * @param newPlanActivity
	 * @param rootRef
	 * @param parentRef
	 * @param number
	 * @throws WTPropertyVetoException
	 * @throws WTException
	 * @author xucr
	 * @throws IOException 
	 * @throws JSONException 
	 * @CreateDate 2020年8月13日
	 */
	private PlanActivity createPlanActivity(Project2 project2, ObjectReference rootRef, 
			ObjectReference parentRef, APQPPlanactivityBean planBean, JSONObject planInfo,
			boolean isChildren) throws WTPropertyVetoException, WTException, IOException, JSONException {
		
		PlanActivity newPlanActivity = PlanActivity.newPlanActivity(WTContainerRef.newWTContainerRef(project2));
		newPlanActivity.setName(planBean.getPlanName());
    	newPlanActivity.setTypeDefinitionReference(TypedUtility.getTypeDefinitionReference(APQPProjectConstant.APQP_PLANACTIVITY));
    	newPlanActivity.setLineNumber(planBean.getLineNumber());
    	newPlanActivity.setParentReference(parentRef);
    	newPlanActivity.setRootReference(rootRef);
    	newPlanActivity.setConstraintType(DateConstraint.ASAP);
    	double duration_number = 1;
    	String duration_unit = "DAYS";
    	Duration duration = ProcessorUtils.getDuration(duration_number, duration_unit);
    	newPlanActivity.setDuration(duration);
    	
    	if(StringUtils.isNotEmpty(planBean.getStartdate())) {
    		String date = getDate(planBean.getStartdate());
    		newPlanActivity.setStartDate(TMUtil.getTimestamp(date));
    	}else{
    		newPlanActivity.setStartDate(null);
    	}
    	if(StringUtils.isNotEmpty(planBean.getFinishdate())) {
    		String date = getDate(planBean.getFinishdate());
    		newPlanActivity.setFinishDate(TMUtil.getTimestamp(date));
    	}else{
    		newPlanActivity.setFinishDate(null);
    	}
    	newPlanActivity.setPlannableState(PlannableState.SCHEDULED);
    	newPlanActivity.setOwnership(Ownership.newOwnership(planBean.getUser()));
    	if(isChildren) {//存在子项，用于在OOTB页面展开
    		newPlanActivity.setSummary(true);
    	}
    	
    	PersistenceHelper.manager.save(newPlanActivity);
    	newPlanActivity = (PlanActivity) PersistenceHelper.manager.refresh(newPlanActivity);
    	
    	if(null != planInfo) {
    		setPlanactivitySTDAttr(newPlanActivity, planInfo);
    	}
    	
    	return newPlanActivity;
	}
	
	/**
	 * 解析创建、同步时，各计划的时间
	 * @param dateObj
	 * @return
	 * @throws JSONException
	 * @author xucr
	 * @CreateDate 2020年10月13日
	 */
	public String getDate(Object dateObj) throws JSONException {
		String date = "";
		if(dateObj instanceof JSONArray) {//同步、更新时
			date = ((JSONArray) dateObj).getString(0);
		} else if(dateObj instanceof String) {//创建时
			date = (String) dateObj;
		}
		return date;
	}
	
	/**
	 * 更新活动
	 * @param activity
	 * @param planInfo
	 * @return
	 * @throws WTPropertyVetoException
	 * @throws WTException
	 * @throws IOException
	 * @throws JSONException
	 * @author xucr
	 * @CreateDate 2020年9月7日
	 */
	public PlanActivity updatePlanActivity(PlanActivity activity, 
			APQPPlanactivityBean planBean, JSONObject planInfo) throws WTPropertyVetoException, WTException, IOException, JSONException {
		
		activity.setStartDate(TMUtil.getTimestamp(planBean.getStartdate()));
		activity.setFinishDate(TMUtil.getTimestamp(planBean.getStartdate()));
		activity.setOwnership(Ownership.newOwnership(planBean.getUser()));
    	
    	//待测试，是否需要------
    	HealthStatusType healthstatustype = HealthStatusType.getHealthStatusTypeDefault();
    	activity.setHealthStatusType(healthstatustype);
    	
    	PersistenceHelper.manager.save(activity);
    	activity = (PlanActivity) PersistenceHelper.manager.refresh(activity);
    	
    	if(null != planInfo) {
    		setPlanactivitySTDAttr(activity, planInfo);
    	}
    	return activity;
	}
	
	/**
	 * 创建or更新交付物文档
	 * @param project
	 * @param planactivity
	 * @param fileName
	 * @param filePath
	 * @param des
	 * @return
	 * @author xucr
	 * @throws Exception 
	 * @CreateDate 2020年8月27日
	 */
	public WTDocument createOrUpdateReportDoc(
			Project2 project, PlanActivity planactivity, String fileName, String filePath, String des) throws Exception {
		WTDocument doc = null;
		String fileInformation = filePath + File.separator + fileName;
		File file = new File(fileInformation);
		List<PlanDeliverable> planDeliverables = ProjectUtil.getDeliverableWithSubjectByActivity(planactivity, false);
		if(null != planDeliverables && planDeliverables.size() > 0) {
			PlanDeliverable planDeliverable = planDeliverables.get(0);
			VersionReference subject = planDeliverable.getSubject();
			Persistable p = subject.getObject();
			if(p instanceof WTDocument) {
				doc = (WTDocument) p;
				GenericUtil.updatePrimaryContent(doc, file);
			} else {
				doc = createReportDoc(project, planactivity, fileName, fileInformation, des);
				if (doc instanceof Iterated) {
					planDeliverable.setSubject(VersionReference.newVersionReference((Iterated) doc));
					PersistenceHelper.manager.save(planDeliverable);
					PersistenceHelper.manager.refresh(planDeliverable);
				}
				return doc;
			}
		} else {
			doc = createReportDoc(project, planactivity, fileName, fileInformation, des);
			addDeliverableSubject(planactivity, doc);
		}
		if(null != doc) {
			file.delete();
		}
		return doc;
	}
	
	/**
	 * 创建交付文档
	 * @author xucr
	 * @CreateDate 2020年8月27日
	 */
	private WTDocument createReportDoc(Project2 project, PlanActivity planactivity, String fileName, String filePath, String des) throws Exception {
		String number = DBUtil.getNextValue("WTDOCUMENTID_seq", 10);
//		WTContainer container = project.getContainer();

		JSONObject obj = new JSONObject();
		String [] stdAttrs = {"apqp"};
		getPlanactivitySTDAttr(planactivity, stdAttrs, obj);
		String apqp = obj.getString("apqp");
		
		Folder folder = GenericUtil.getFolder("/Default/" + apqp, project);
		
		WTDocument doc = GenericUtil.createWTDocument(number, fileName, 
				APQPProjectConstant.APQP_DELIVERYDOC, project, folder, des, null, filePath);
		
		return doc;
	}
	
	/**
	 * 添加交付物主题
	 * @param planActivityOid
	 * @param doc
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年8月27日
	 */
	public void addDeliverableSubject(PlanActivity activity, WTDocument doc) throws WTException {
		/**
		 * 规则：
		 * 1、 以任务名称作为交付物名称
		 * 2、 一个任务只会上载一封交付物，第二次上载交付物则为更新
		 * */
		try {
			List<PlanDeliverable> planDeliverables = ProjectUtil.getDeliverableWithSubjectByActivity(activity, false);
			PlanDeliverable planDeliverable = null;
			if(null != planDeliverables && planDeliverables.size() > 0) {
				planDeliverable = planDeliverables.get(0);
			} else {
				planDeliverable = addDeliverables(activity, activity.getName());//以任务名称作为交付物名称
			}
			
			if (doc instanceof Iterated) {
				planDeliverable.setSubject(VersionReference.newVersionReference((Iterated) doc));
			}
			
			PersistenceHelper.manager.save(planDeliverable);
			PersistenceHelper.manager.refresh(planDeliverable);
		} catch (WTPropertyVetoException e) {
			e.printStackTrace();
			logger.error("addDeliverableSubject >>>catch >>>>>: " + e.getLocalizedMessage());
		}
	}
	
	/**
	 * 创建一个空的可交付结果
	 * @param planactivity
	 * @param deliveryName
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年8月27日
	 */
	public PlanDeliverable addDeliverables(PlanActivity planactivity, String deliveryName) throws WTException {
		PlanDeliverable plandeliverable = null;
		try {
			if(null != planactivity) {
				Plan plan = (Plan) planactivity.getRoot();
				Plannable plannable = (Plannable) planactivity.getParentPlannable();
				plandeliverable = PlanDeliverable.newPlanDeliverable(plannable);
				plandeliverable.setDomainRef(AdminUtils.getAdministrativeSystemDomainRef(((Plannable) (plannable)).getContainerReference()));
				plandeliverable.setSubject(null);
				plandeliverable.setParent(plan);
				plandeliverable.setName(deliveryName);
				plandeliverable = (PlanDeliverable) PersistenceHelper.manager.save(plandeliverable);

				PlanDeliverableLink plandeliverablelink = PlanDeliverableLink.newPlanDeliverableLink(planactivity, plandeliverable);
				PersistenceHelper.manager.save(plandeliverablelink);
			}
		} catch (WTPropertyVetoException wtpropertyvetoexception) {
			throw new WTException(wtpropertyvetoexception.getLocalizedMessage(SessionHelper.getLocale()));
		}
		return plandeliverable;
	}
	
	/**
	 * 解除交付物与主题的关联
	 * @param deliverableOid
	 * @throws WTException
	 * @throws WTPropertyVetoException
	 * @author xucr
	 * @throws JSONException 
	 * @CreateDate 2020年9月1日
	 */
	public boolean deleteDeliverySubject(String deliverableOid) throws WTException, WTPropertyVetoException, JSONException {
		boolean isTrue = false;
		PlanDeliverable deliverable = (PlanDeliverable) TMUtil.oid2Obj(deliverableOid);
		if(null != deliverable) {
			deliverable.setSubject(null);
			PersistenceHelper.manager.save(deliverable);
			isTrue = true;
		}
		return isTrue;
	}
	
	/**
	 * 设置活动标准属性
	 * @param plan
	 * @param projectBean
	 * @throws IOException
	 * @throws WTException
	 * @author xucr
	 * @throws JSONException 
	 * @CreateDate 2020年8月13日
	 */
	public void setPlanactivitySTDAttr(PlanActivity plan, JSONObject projectBean) throws JSONException, WTException {
		PersistableAdapter pa = new PersistableAdapter(plan, APQPProjectConstant.APQP_PLANACTIVITY, SessionHelper.getLocale(), null);
		pa.load(PLANACTIVITY_MDA_ATTRS);
		for(int i = 0; i < PLANACTIVITY_MDA_ATTRS.length; i++) {
			if(projectBean.has(PLANACTIVITY_MDA_ATTRS[i]))
				pa.set(PLANACTIVITY_MDA_ATTRS[i], projectBean.getString(PLANACTIVITY_MDA_ATTRS[i]));
		}
		pa.validate();
		pa.apply();
		PersistenceHelper.manager.save(plan);
	}
	
	/**
	 * 初始化活动表格列（创建时）
	 * @return
	 * @throws DocumentException
	 * @throws IOException
	 * @throws JSONException
	 * @author xucr
	 * @throws WTException 
	 * @throws ViewException 
	 * @CreateDate 2020年8月20日
	 */
	public JSONObject initPlanGrid(String partNumber) throws DocumentException, IOException, JSONException, ViewException, WTException {
		String materialCategoryKey = APQPConfig.getKey("MaterialCategory");
		JSONObject rsult = new JSONObject();
		JSONArray columns = new JSONArray();
		if(StringUtils.isNotEmpty(materialCategoryKey)) {
			String[] materialCategorys = materialCategoryKey.split(APQPProjectConstant.SPLITVALUE);
			String[] phases = getPhase(null);
			
			Map<String, WTPart> map = getWTPart(partNumber, materialCategorys);
			
			//定义数据
			List<Object> datalist = new ArrayList<Object>();
			Map<String, String> obj = null;
			for (Entry<String, WTPart> se : map.entrySet() ){
				obj = new LinkedHashMap<String, String>();//有顺序的map
				WTPart part = se.getValue();
				for( int j = 0 ; j < phases.length; j++) {
					obj.put("materialCategory",ProjectUtil.getPartCNAndENName(part));
					obj.put("pn",part.getNumber());
					obj.put("supplier",(String) IBAUtil.getIBAValue(part, "partSupplier"));
					obj.put("owner","");
					obj.put(phases[j],"");
				}
				datalist.add(obj);
			}
			
			initGridColumns(columns);
			
			rsult.put("count", datalist.size());
			rsult.put("data", datalist);
			rsult.put(ProcessService.COLUMNS, columns);
			rsult.put("code", "0");
			rsult.put("msg", "");
			rsult.put("canEdit", false);//创建时，直接不允许修订
		} else {
			rsult.put("count", 0);
			rsult.put("data", new JSONArray());//当没有数据时，要返回[]
			
			rsult.put(ProcessService.COLUMNS, columns);
			rsult.put("code", "1");
			rsult.put("msg", "您查询的数据不存在!");
		}
		return rsult;
	}
	
	/**
	 * 匹配已更新的内容
	 * @param partNumber
	 * @param nums 历史APQP已存在的料号
	 * @return
	 * @throws DocumentException
	 * @throws IOException
	 * @throws JSONException
	 * @throws ViewException
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年8月20日
	 */
	public JSONObject initPlanGrid(Project2 project, List<String> nums) throws DocumentException, IOException, JSONException, ViewException, WTException {
		String materialCategoryKey = APQPConfig.getKey("MaterialCategory");
		JSONObject rsult = new JSONObject();
		
		List<String> addNums = new ArrayList<String>();//变更后增加的料号
		List<String> delNums = new ArrayList<String>();//变更后删减的料号
		delNums.addAll(nums);
		
		if(StringUtils.isNotEmpty(materialCategoryKey)) {
			String[] materialCategorys = materialCategoryKey.split(APQPProjectConstant.SPLITVALUE);
			String [] phases = getPhase(project); //从实际APQP中取，再次同步的项目，以本身列为主
			
			JSONObject result = new JSONObject();
			String [] stdAttrs = {"modelName"};
			projectservice.getProjectSTDAttr(project, stdAttrs, result);
			String partNumber =  result.getString("modelName");
			Map<String, WTPart> map = getWTPart(partNumber, materialCategorys);
			logger.info("map:" + map);
			logger.info("map.size()" + map.size());
			
			//定义数据
			List<Object> datalist = new ArrayList<Object>();
			JSONObject obj = null;
			JSONArray array = null;
			for (Entry<String, WTPart> se : map.entrySet() ) {
				obj = new JSONObject();
				WTPart part = se.getValue();
				String _partNumber = part.getNumber();
				if(!nums.contains(_partNumber)) { //新增
					for( int j = 0 ; j < phases.length; j++) {
						obj.put("materialCategory", ProjectUtil.getPartCNAndENName(part));
						obj.put("pn",_partNumber);
						obj.put("supplier",(String) IBAUtil.getIBAValue(part, "partSupplier"));
						obj.put("owner","");
						
						//应前端要求，当有新增的料号时，apqp对应的返回值也为数组
						array =  new JSONArray();
						array.put(""); array.put(""); array.put("");
						obj.put(phases[j],array);
						
						addNums.add(_partNumber);
					}
					datalist.add(obj);
				} else {
					delNums.remove(_partNumber);
				}
			}
			
			rsult.put("count", datalist.size());
			rsult.put("data", datalist);
			rsult.put("delNums", delNums);
			rsult.put("code", "0");
			rsult.put("msg", "");
		} else {
			rsult.put("count", 0);
			rsult.put("data", new JSONArray());//当没有数据时，要返回[]
			
			rsult.put("code", "1");
			rsult.put("msg", "您查询的数据不存在!");
		}
		return rsult;
	}
	
	/**
	 * 获取phase
	 * @param project
	 * @return
	 * @author xucr
	 * @CreateDate 2020年10月14日
	 */
	public String[] getPhase(Project2 project) {
		String[] phases = {};
		/**
		 * 当存在项目时，从项目中获取阶段
		 * 不存在项目时，从配置中获取
		 * */
		try {
			boolean isProject = false;
			if(null != project) {
				/**
				 * 每个一级计划下面的子计划，其APQP(阶段值)都一样，因此，只需任意取一个即可
				 * 注意：有可能有项目，但是没有计划，这个时候，需要从配置里面拉取，保证phase有值
				 * */
				Plan plan = (Plan) PlanHelper.service.getPlan(ObjectReference.newObjectReference(project));
				List<PlanActivity> plans = ProjectUtil.getAllChildren(plan);
				if(null != plans && plans.size() > 0) {
					PlanActivity child = plans.get(0);
					List<PlanActivity> childs = ProjectUtil.getAllChildren(child);//二级计划
					JSONObject obj = null;
					String [] stdAttrs = {"apqp"};
					List<String> apqps = new ArrayList<String>();
					for(PlanActivity cpa : childs) {
						obj = new JSONObject();
						getPlanactivitySTDAttr(cpa, stdAttrs, obj);
						String apqp = obj.getString("apqp");
						if(!apqps.contains(apqp)) {
							apqps.add(apqp);
						}
					}
					if(apqps.size() > 0) {
						phases = apqps.toArray(new String[apqps.size()]) ;
					} else {
						isProject = true;
					}
				} else {
					isProject = true;
				}
			}
			if(null == project || isProject) {
				String phaseKey = APQPConfig.getKey("phase");
				if(StringUtils.isNotEmpty(phaseKey)) {
					phases = phaseKey.split(APQPProjectConstant.SPLITVALUE);
				}
			}
		} catch (WTException e) {
			e.printStackTrace();
		} catch (JSONException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return phases ;
	}
	
	/**
	 * 查询单个活动详情1
	 * @param activityOid
	 * @return
	 * @throws WTException
	 * @throws JSONException
	 * @throws IOException
	 * @author xucr
	 * @CreateDate 2020年8月26日
	 */
	public JSONObject findPlanActivity(String activityOid) throws WTException, JSONException, IOException {
		PlanActivity activity = (PlanActivity) TMUtil.oid2Obj(activityOid);
		JSONObject result = findPlanActivity(activity);
		return result;
	}
	/**
	 * 查询单个活动详情2
	 * @param planactivity
	 * @return
	 * @throws WTException
	 * @throws JSONException
	 * @throws IOException
	 * @author xucr
	 * @CreateDate 2020年8月26日
	 */
	public JSONObject findPlanActivity(PlanActivity planactivity) throws WTException, JSONException, IOException {
		
		JSONObject result = new JSONObject();
		if(null != planactivity) {
			Project2 project = (Project2) planactivity.getContainer();
			WTUser u = (WTUser) SessionHelper.manager.getPrincipal();
			JSONObject proInfo = projectservice.findAPQP(project, u, APQPProjectService.READPROJECTTYPE[0]);
			JSONObject planInfo = new JSONObject();
			getPlanactivitySTDAttr(planactivity, null, planInfo);
			findDelivery(planactivity, planInfo, true, true);
			
			result.put("basicInfo", proInfo);
			result.put("fileInfo", planInfo);
		}
		return result;
	}
	
	/**
	 * 查询交付详情
	 * @param activity
	 * @param proInfo
	 * @param isOnlyOne 是否查询单个活动
	 * @param isLabel 交付物的链接是否需要带<a>
	 * @return
	 * @throws WTException
	 * @throws IOException
	 * @author xucr
	 * @throws JSONException 
	 * @CreateDate 2020年8月26日
	 */
	public void findDelivery(PlanActivity activity, JSONObject proInfo, boolean isOnlyOne, boolean isLabel) throws WTException, IOException, JSONException {
		
		List<PlanDeliverable> delivers = ProjectUtil.getDeliverableWithSubjectByActivity(activity, false);
		if(null != delivers && delivers.size() > 0) {
			JSONObject obj = new JSONObject();
			String [] stdAttrs = {"apqp"};
			getPlanactivitySTDAttr(activity, stdAttrs, obj);
			String apqp = obj.getString("apqp");
			
			PlanDeliverable deliver = delivers.get(0);//只会有一封交付物，在上载的实现逻辑中已控制
			Map<String, String> map = ProjectUtil.getDeliveryUrlLink(deliver, true, isLabel);
//			String modifyTime = TMUtil.timestampToString(deliver.getModifyTimestamp(),"yyyy-MM-dd HH:mm:ss");
			String modifyTime = "";
			WTDocument doc = ProjectUtil.getDeliveryDOc(deliver);
			if(null != doc) {
				modifyTime = TMUtil.timestampToString(doc.getModifyTimestamp(),"yyyy-MM-dd HH:mm:ss");
			}
			
			/**此方法作为通用方法，单个查询活动时通用，有可能查询项目时，一行有多个活动被查询，因此返回值要做区分
			 * 单个查询时，带链接的交付物的key为url
			 * 多个查询时，带连接的交付物的key为"apqp"
			 * */
			if(isOnlyOne) {
				proInfo.put("url", map.get(ProjectUtil.URLLINK));
				proInfo.put("modifyTime", modifyTime);
				proInfo.put("deliveryOid", TMUtil.obj2Oid(deliver));
				proInfo.put("show", true);//true 允许编辑，应前端要求，当项目在流程中时，则不允许编辑
			} else {
				JSONArray ay = proInfo.getJSONArray(apqp);
				JSONArray array = new JSONArray();
				array.put(ay.getString(0));//第一个为时间
				array.put(map.get(ProjectUtil.URLLINK));//第二个为交付物链接
				array.put(map.get(ProjectUtil.FILENAME));//第三个为交付物附件名称
				proInfo.put(apqp, array);//时间|交付文档url|交付文档附件名称
				proInfo.put(apqp + "_modifyTime", modifyTime);
				proInfo.put(apqp + "_deliveryOid", TMUtil.obj2Oid(deliver));
				proInfo.put(apqp + "_show", true);//true 允许编辑，应前端要求，当项目在流程中时，则不允许编辑
			}
		}
	}
	
	/**
	 * 查询项目的所有活动
	 * @param project
	 * @param isCreateProcess 是否启动流程时
	 * @return
	 * @throws DocumentException
	 * @throws IOException
	 * @throws JSONException
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年8月21日
	 */
	public JSONObject getPlanActivityView(Project2 project) throws DocumentException, IOException, JSONException, WTException {
		JSONObject rsult = new JSONObject();
		if(null != project) {
			JSONArray columns = new JSONArray();
			Plan plan = (Plan) PlanHelper.service.getPlan(ObjectReference.newObjectReference(project));
			List<PlanActivity> plans = ProjectUtil.getAllChildren(plan);
			List<Object> datalist = new ArrayList<Object>();
			if(null != plans && plans.size() > 0) {
				List<String> dateColumn = new ArrayList<String>();
				JSONObject obj = null;
				Map<String, String> classMap = new LinkedHashMap<String, String>();//有顺序的map
				String [] stdAttrs = {"apqp","pn","supplier","materialCategory", "isStandard"};
				WTPrincipalReference u = null;
				JSONArray array = null;
				
				classMap.put("materialCategory", APQPProjectConstant.APQP_PLANACTIVITY_FIXEDCOLUMN[0]);
				classMap.put("pn", APQPProjectConstant.APQP_PLANACTIVITY_FIXEDCOLUMN[1]);
				classMap.put("supplier", APQPProjectConstant.APQP_PLANACTIVITY_FIXEDCOLUMN[2]);
				classMap.put("owner", APQPProjectConstant.APQP_PLANACTIVITY_FIXEDCOLUMN[3]);
				
				for(PlanActivity pa : plans) {
					obj = new JSONObject();
					
					List<PlanActivity> childs = ProjectUtil.getAllChildren(pa);
					for(PlanActivity cpa : childs) {
						
						getPlanactivitySTDAttr(cpa, stdAttrs, obj);
						classMap.put(obj.getString("apqp"), TMUtil.conversion(obj.getString("apqp")));
						
						//所有子项都是同一个owner、materialCategory、pn、hierarchy、supplier
						u = cpa.getOwnership().getOwner();
						obj.put("owner",StringUtils.isNotEmpty(u.getFullName()) ? u.getFullName() : "");
						obj.put("ownerKey",StringUtils.isNotEmpty(u.getName()) ? u.getName() : "");
						array = new JSONArray();
						array.put(TMUtil.timestampToString(cpa.getStartDate(),"yyyy-MM-dd"));//时间
						array.put("");//交付文档下载链接，在下面findDelivery()会有查询，应前端要求，在无值得情况下也要返回下标
						array.put("");//交付文档名称，在下面findDelivery()会有查询，应前端要求，在无值得情况下也要返回下标
						obj.put(obj.getString("apqp"), array);
						obj.put(obj.getString("apqp") + "_" + APQPProjectConstant.PLANACTIVITYOID, TMUtil.obj2Oid(cpa));
						
						/**在审批页面时，判断当前活动报告的状态:
						 * 已上载、已达标，正常状态 1 ，正常状态（显示驳回按钮）
						 * 已上载、未达标，驳回状态 2 ，驳回状态（显示通过按钮）
						 * 活动已关闭，仅展示                                             （不显示任何操作）
						 * */
						if(PlannableState.COMPLETED.equals(cpa.getPlannableState())) {
							obj.put(obj.getString("apqp") + "_type", APQPProjectConstant.STANDARD_3);
						} else {
							if(APQPProjectConstant.YES.equals(obj.getString("isStandard"))
									|| APQPProjectConstant.YES_VALUE.equals(obj.getString("isStandard"))) {
								obj.put(obj.getString("apqp") + "_type", APQPProjectConstant.STANDARD_1);
							} else {
								obj.put(obj.getString("apqp") + "_type", APQPProjectConstant.STANDARD_2);
							}
						}
						findDelivery(cpa, obj, false, false);//补充交付物信息，当任务存在交付物时，obj.getString("apqp")的值会被交付物链接替换
						
						//加入各SQE的任务，用于前端做控件判断
						if(!dateColumn.contains(obj.getString("apqp")))
							dateColumn.add(obj.getString("apqp"));
					}
					datalist.add(obj);
				}
				//当存在活动时，以活动的数据构造表格列
				initGridColumns(classMap, "center", "", columns, null, dateColumn);
			} else {
				//当无活动时，以配置信息构造表格列
				initGridColumns(columns);
			}
			
			rsult.put("count", datalist.size());
			rsult.put("data", datalist);
			rsult.put(ProcessService.COLUMNS, columns);
			rsult.put("code", "0");
			rsult.put("msg", "");
			
			//应前端要求，当项目完成时，且登录者为所有者时，允许修订
			WTUser user = (WTUser) SessionHelper.manager.getPrincipal();
			if(user.getName().equals(project.getOwner().getName())
					&& ContainerTeamManagedState.COMPLETED.equals(project.getContainerTeamManagedInfo().getState())) {
				rsult.put("canEdit", true);
			} else {
				rsult.put("canEdit", false);
			}
		}
		return rsult;
	}
	
	/**
	 * 在流程中查看活动详情
	 * @param project
	 * @return
	 * @throws DocumentException
	 * @throws IOException
	 * @throws JSONException
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年9月9日
	 */
	public JSONObject getPlanActivityView(WfProcess process) throws DocumentException, IOException, JSONException, WTException {
		JSONObject rsult = new JSONObject();
		if(null != process) {
			FormDataXml xml = processService.findFormDataXml(process, null);
			Blob blob = xml.getFormcontent();
			String str = ProjectUtil.blob2str(blob);
			JSONObject _str = new JSONObject(str);
			JSONArray columns = null;
			if(_str.has(ProcessService.COLUMNS)) {
				columns = _str.getJSONArray(ProcessService.COLUMNS);
			} else {
				columns = new JSONArray();
			}
			List<String> oids = new ArrayList<String>();
			if(_str.has(ProcessService.REJECTOID)) {
				String rejectOids = _str.getString(ProcessService.REJECTOID);
				String [] _oids = rejectOids.split(APQPProjectConstant.SPLITVALUE);
				oids = Arrays.asList(_oids);
			}
			List<Object> datalist = new ArrayList<Object>();
			JSONArray planData = null;//审批的表格信息
			if(_str.has(ProcessService.ACTIVITYSINFO)) {
				planData = _str.getJSONArray(ProcessService.ACTIVITYSINFO);
				JSONObject obj = null;
				String [] stdAttrs = {"apqp"};
				for(int i = 0 ; i < planData.length(); i++) {
					obj = planData.getJSONObject(i);
					
					Iterator<String> it = obj.keys();
					JSONObject attrs = null;
					while(it.hasNext()) {
						String key = it.next();
						if(key.contains(APQPProjectConstant.PLANACTIVITYOID)) {
							attrs = new JSONObject();
							PlanActivity activity = (PlanActivity) TMUtil.oid2Obj(obj.getString(key));
							getPlanactivitySTDAttr(activity, stdAttrs, attrs);
							
							//如果存在被驳回的，需要重新展示状态
							if(oids.contains(TMUtil.obj2Oid(activity))) {//被驳回，为3的状态已经在流程发起时加入在其中
								obj.put(attrs.getString("apqp") + "_type", APQPProjectConstant.STANDARD_2);
							}
						}
					}
					datalist.add(obj);
				}
			}
			rsult.put("count", datalist.size());
			rsult.put("data", datalist);
			rsult.put(ProcessService.COLUMNS, columns);
			rsult.put("code", "0");
			rsult.put("msg", "");
		}
		return rsult;
	}
	
	/**
	 * 查询活动的标准属性
	 * @param planactivity
	 * @param stdAttrs 标准属性，当为空时，设定默认值
	 * @param result
	 * @throws WTException
	 * @throws JSONException
	 * @author xucr
	 * @CreateDate 2020年8月24日
	 */
	public void getPlanactivitySTDAttr(PlanActivity planactivity, String [] stdAttrs, JSONObject result) throws WTException, JSONException {
		if(null != planactivity) {
			if(null == stdAttrs || stdAttrs.length <= 0) {
				stdAttrs = PLANACTIVITY_MDA_ATTRS;
			}
			PersistableAdapter pa = new PersistableAdapter(planactivity, APQPProjectConstant.APQP_PLANACTIVITY, SessionHelper.getLocale(), null);
			pa.load(Arrays.asList(stdAttrs));//必须要先load再set
			for(int i = 0 ; i < stdAttrs.length; i++) {
				String key = stdAttrs[i];
				String value = (String) pa.get(key);
				if(PLANACTIVITY_ENUM_ATTRS2.containsKey(key)) {//如果是枚举
					Map<String,String> maps = EnumerationUtil.getEnumerationValues(PLANACTIVITY_ENUM_ATTRS2.get(key));
					value = maps.get(value);
				}
				result.put(stdAttrs[i], TMUtil.conversion(value));
			}
		}
	}
	
	/**
	 * 查询活动的标准属性（专用方法：用于查询项目时，汇总一列在表格显示信息）
	 * @param planactivity
	 * @param stdAttrs 标准属性，当为空时，设定默认值
	 * @param result
	 * @throws WTException
	 * @throws JSONException
	 * @author xucr
	 * @CreateDate 2020年8月24日
	 */
	public void getPlanactivitySTDAttr2(PlanActivity planactivity, String [] stdAttrs, JSONObject result) throws WTException, JSONException {
		if(null != planactivity) {
			if(null == stdAttrs || stdAttrs.length <= 0) {
				stdAttrs = PLANACTIVITY_MDA_ATTRS;
			}
			PersistableAdapter pa = new PersistableAdapter(planactivity, APQPProjectConstant.APQP_PLANACTIVITY, SessionHelper.getLocale(), null);
			pa.load(Arrays.asList(stdAttrs));//必须要先load再set
			for(int i = 0 ; i < stdAttrs.length; i++) {
				String key = stdAttrs[i];
				String value = (String) pa.get(key);
				if(PLANACTIVITY_ENUM_ATTRS2.containsKey(key)) {//如果是枚举
					Map<String,String> maps = EnumerationUtil.getEnumerationValues(PLANACTIVITY_ENUM_ATTRS2.get(key));
					value = maps.get(value);
				}
				
				if(result.has(stdAttrs[i])) {
					String t = (String) result.get(stdAttrs[i]);
					result.put(stdAttrs[i], t + "</br>" + TMUtil.conversion(value));
				} else {
					result.put(stdAttrs[i], TMUtil.conversion(value));
				}
			}
		}
	}
	
	public Map<String, WTPart> getWTPart(String partNumber, String[] keys) throws ViewException, WTException, RemoteException {
		/**
		 * 成品料号：
		 * 1、必须是生效视图
		 * 2、最新版本
		 * 3、所有原材料，匹配中英文：BOM下所有原材料 的 英文名称(IBA属性) = 配置中MaterialCategory的值
		 * 
		 * */
		
		//得到所有的视图
//		View[] views = ViewHelper.service.getAllViews();
		WTPart part = PartUtil.getWTPartByNumber(partNumber);
		WTArrayList parts = PartWorkflowUtil.getAllPartViews(part);// 获取视图
		
		List<WTPart> list = new ArrayList<WTPart>();
		if(null != parts && parts.size() > 0) {
			for(int i = 0 ; i < parts.size() ; i++) {
				WTPart p = (WTPart) ((ObjectReference)parts.get(i)).getObject();
				ProjectUtil.getChildPart(p, APQPProjectConstant.WTPART_RAWMATERIAL, list);
			}
		}
		Map<String, WTPart> map = new HashMap<String, WTPart>();
		if(null != list) {
			List<String> ks = Arrays.asList(keys);
			for(WTPart p : list) {
//				String enName = (String) IBAUtil.getIBAValue(p, PARTCNANDENNAME);//原材料中英文名称
				String cnAndEnName = ProjectUtil.getPartCNAndENName(p);
				logger.info(p.getNumber() + "的中英文名称：" + cnAndEnName);
				if(ks.contains(cnAndEnName)) {
					map.put(p.getNumber(), p);
				}
			}
		}
		return map;
	}
	
	/**
	 * 初始化表格列（用于项目无活动）
	 * @param columns
	 * @throws DocumentException
	 * @throws IOException
	 * @throws JSONException
	 * @author xucr
	 * @CreateDate 2020年10月14日
	 */
	public void initGridColumns(JSONArray columns) throws DocumentException, IOException, JSONException {
		String[] phases = getPhase(null);
		//定义数据列
		Map<String, String> classMap = new LinkedHashMap<String, String>();//有顺序的map
		//定义编辑列 key
		List<String> editColumn = new ArrayList<String>();
		
		classMap.put("materialCategory", APQPProjectConstant.APQP_PLANACTIVITY_FIXEDCOLUMN[0]);
		classMap.put("pn", APQPProjectConstant.APQP_PLANACTIVITY_FIXEDCOLUMN[1]);
		classMap.put("supplier", APQPProjectConstant.APQP_PLANACTIVITY_FIXEDCOLUMN[2]);
		classMap.put("owner", APQPProjectConstant.APQP_PLANACTIVITY_FIXEDCOLUMN[3]);
		
		for( int j = 0 ; j < phases.length; j++) {
			classMap.put(phases[j], phases[j]);
			editColumn.add(phases[j]);
		}
		initGridColumns(classMap, "center", "", columns, null, editColumn);
	}
	
	/**
	 * 初始化表格（格式）
	 * @param project
	 * @param titles 表格filed名、列名
	 * @param align 对其方式
	 * @param width 列宽
	 * @param columns 返回所有列
	 * @param fixeds 固定列
	 * @param dateColumns 时间列
	 * @throws JSONException
	 * @author xucr
	 * @CreateDate 2020年8月14日
	 */
	private void initGridColumns(Map<String,String> titles, String align, String width, 
			JSONArray columns, List<String> fixeds,List<String> dateColumns) throws JSONException {
		JSONObject obj = null;
//		boolean isDraft = isDraft(project);
		for(String title : titles.keySet()) {
			obj = new JSONObject();
			if(null != fixeds && fixeds.contains(title)) {
				obj.put("fixed", "left");
			}
			obj.put("field", title);
			obj.put("title", titles.get(title));
			obj.put("align", align);
			if(StringUtils.isNotEmpty(width)) {//如果不设置宽度，则表格自动等比设置宽度
				obj.put("width", width);
			}
			/**
			 * 应前端要求：
			 * 编制活动时，各表格列
			 * date：时间控件，可修改时间，适用于创建项目、编辑项目草稿
			 * file：展示内容，不可修改，当存在交付物时展示交付物链接，否则展示任务的时间
			 * */
			if(null != dateColumns && dateColumns.contains(title)) {
//				if(isDraft) {
//					obj.put("type", "date");
//				} else {
//					obj.put("type", "static");
//				}
				//to-be: 仅返回类型date
				obj.put("type", "date");
			}
			
			/**
			 * 应前端要求：
			 * 编制活动时，各表格列
			 * user：用户组件，可修改，适用于创建项目、编辑项目草稿
			 * static：展示内容，不可修改
			 * */
			if("owner".equals(title)) {//该列用于选择输入人员
				//当创建项目、编辑草稿时，责任人可编辑，其他状态仅查看
//				if(isDraft) {
//					obj.put("type", "user");
//				} else {
//					obj.put("type", "static");
//				}
				//to-be: 仅返回类型user
				obj.put("type", "user");
			}
			obj.put("sort", false);
			columns.put(obj);
		}
	}
	
	/**
	 * 判断是否有效项目
	 * @param project
	 * @return
	 * @author xucr
	 * @CreateDate 2020年9月9日
	 */
	public boolean isDraft(Project2 project) {
		/**
		 * 有效项目定义：非草稿状态
		 * */
		boolean isDraft = false;
		if(null == project 
						|| ContainerTeamManagedState.DEFINED.equals(project.getContainerTeamManagedInfo().getState())) {
			isDraft = true;
		}
		return isDraft;
	}
	
	/**
	 * 修订
	 * @param planActivityOid
	 * @return
	 * @throws WTPropertyVetoException
	 * @throws WTException
	 * @author xucr
	 * @throws JSONException 
	 * @CreateDate 2020年8月31日
	 */
	public String revise(String planActivityOid) throws WTPropertyVetoException, WTException, JSONException {
		/**
		 * 改变项目状态：进行中
		 * 改变任务状态：进行中、已上载、不达标
		 * 
		 * 条件：
		 * 	仅完成的项目
		 * */
		String tip = "";
		PlanActivity activity = (PlanActivity) TMUtil.oid2Obj(planActivityOid);
		if(null != activity) {
			Project2 project = (Project2) activity.getContainer();
			ContainerTeamManagedInfo ctinfo = project.getContainerTeamManagedInfo();
			ContainerTeamManagedState state = ctinfo.getState();
			//正常情况，项目完成，则活动一定完成，防止有异常数据：项目完成，而活动未完成，这里也将活动状态加入
			if(ContainerTeamManagedState.COMPLETED.equals(state) 
					&& PlannableState.COMPLETED.equals(activity.getPlannableState())) {
				JSONObject projectBean = new JSONObject();
				projectBean.put("isUpload", APQPProjectConstant.YES);
				projectBean.put("isStandard", APQPProjectConstant.NO);
				
				activity.setPlannableState(PlannableState.INPROCESS);
				setPlanactivitySTDAttr(activity, projectBean);
				
				ctinfo.setState(ContainerTeamManagedState.RUNNING);
				ctinfo.setActualEnd(null);
				project.setContainerTeamManagedInfo(ctinfo);
				
				PersistenceHelper.manager.save(project);
				PersistenceHelper.manager.save(activity);
				
				PersistenceHelper.manager.refresh(project);
				PersistenceHelper.manager.refresh(activity);
			} else {
				tip = APQPProjectConstant.TIP3;
			}
		}
		return tip;
	}
}
